package com.ruoyi.boat.codec;

import com.ruoyi.boat.utils.ByteUtil;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Arrays;

@Slf4j
public class BdCodec {

    public static BdRes getRevMsgFromBd4Dot0(byte[] bdBytes) {
        //解析TXXX
        BdRes res = new BdRes();
        res.setContent(Arrays.copyOfRange(bdBytes, 18, bdBytes.length - 2));
        res.setBdNo(ByteUtil.bytesToInt(Arrays.copyOfRange(bdBytes, 11, 14)) + "");
        return res;
    }

    /**
     * 解析北斗2.1 BDTXR
     * $BDTXR,1,0242286,2,,A468656C6C6FB1B1B6B7*46 混合编码
     */
    public static BdRes getRevMsgFromBd2Dot1(byte[] bdBytes) {
        String bdRev = new String(bdBytes, StandardCharsets.UTF_8);
        String[] bdRevSplit = bdRev.split("[*,]");
        BdRes res = new BdRes();
        res.setBdNo(bdRevSplit[2]);
        res.setContent(ByteUtil.hexStrToBytes(bdRevSplit[5]));
        return res;
    }

    /**
     * 回复 $BDFKI,TXA,Y,Y,0,0060*15
     */
    public static BdRes getSendResFromBd2Dot1(byte[] bdBytes) {
        String bdRev = new String(bdBytes, StandardCharsets.UTF_8);
        String[] bdRevSplit = bdRev.split("[*,]");
        BdRes res = new BdRes();
        res.setType(bdRevSplit[1]);
        boolean result = "Y".equals(bdRevSplit[2]);
        res.setFlag(result);
        if (result) {
            res.setMsg("发送成功");
        } else if (!"".equals(bdRevSplit[5])) {
            res.setMsg("发送频率未到，还需" + Integer.parseInt(bdRevSplit[5]) + "秒");
        } else {
            res.setMsg("发送失败");
        }
        return res;
    }

    public static BdRes getSendResFromBd4Dot0(byte[] bdBytes) {
        BdRes res = new BdRes();
        res.setFlag(false);
        if (bdBytes[10] == 0x01) {
            res.setMsg("发送失败");
        } else if (bdBytes[10] == 0x02) {
            res.setMsg("蘑菇头信号未锁定");
        } else if (bdBytes[10] == 0x03) {
            res.setMsg("蘑菇头电量不足");
        } else if (bdBytes[10] == 0x04) {
            res.setMsg("发射频率未到，还需" + ByteUtil.bytesToInt(Arrays.copyOfRange(bdBytes, 11, 15)) + "秒");
        } else {
            res.setFlag(true);
        }
        return res;
    }

    public static BdRes getRevMsgFromBd3(String bdMessage) {
        BdRes res = new BdRes();
        res.setContent(ByteUtil.hexToByteArray(bdMessage.split("[,*]")[7]));
        return res;
    }

    public static BdRes getSendResFromBd3(String bdMessage) {
        BdRes res = new BdRes();
        String[] bdMessageSplits = bdMessage.split("[,*]");
        res.setType(bdMessageSplits[2]); //判断如果是 TCQ 就是报文通信申请的回执
        res.setFlag(bdMessageSplits[3].equals("Y"));
        if (bdMessageSplits[4].equals("1")) {
            //频率未到
            res.setMsg("发送频率未到,还需要" + bdMessageSplits[5] + "秒");
        } else if (bdMessageSplits[4].equals("2")) {
            res.setMsg("发射抑制");
        } else if (bdMessageSplits[4].equals("3")) {
            res.setMsg("发射静默");
        } else if (bdMessageSplits[4].equals("4")) {
            res.setMsg("功率未锁定");
        } else if (bdMessageSplits[4].equals("5")) {
            res.setMsg("未检测到IC模块信息");
        } else if (bdMessageSplits[4].equals("6")) {
            res.setMsg("权限不足");
        }
        return res;
    }

    public static byte[] encodeBd4Dot0SendMsg(byte[] cmd, String localBdNo, String remoteBdNo) {
        String header = "$TXSQ";
        byte[] length = ByteUtil.intToBytes(18 + cmd.length, 2);
        byte[] localAddress = ByteUtil.intToBytes(Integer.parseInt(localBdNo), 3);
        byte[] messageType = new byte[]{0x46};
        byte[] remoteAddress = ByteUtil.intToBytes(Integer.parseInt(remoteBdNo), 3);
        byte[] contentLength = ByteUtil.intToBytes(cmd.length * 8, 2);
        byte[] response = new byte[]{0x00};
        byte[] beCheck = ByteUtil.combineBytes(header.getBytes(StandardCharsets.UTF_8), length, localAddress, messageType
                , remoteAddress, contentLength, response, cmd);
        byte[] checkResult = new byte[]{ByteUtil.xorCheck(beCheck)};
        return ByteUtil.combineBytes(beCheck, checkResult, new byte[]{0x0d, 0x0a});
    }

    /**
     * 创建 2.1 通信申请报文
     * $CCTXA,0242286,1,2,A468656C6C6FB1B1B6B7*7F\r\n
     */
    public static byte[] encodeBd2Dot1SendMsg(byte[] cmd, String localBdNo, String remoteBdNo) {
        String header = "$CCTXA," + remoteBdNo + ",1,1,";
        String content = ByteUtil.bytesToHex(cmd, "") + "*";
        String hplusC = header + content;
        //排除 $和*
        String checkResult = ByteUtil.byteToHex(ByteUtil.xorCheck(hplusC.substring(1, hplusC.length() - 1).getBytes(StandardCharsets.UTF_8)));
        log.info("bd send : {}", hplusC + checkResult);
        return ByteUtil.combineBytes((hplusC + checkResult).getBytes(StandardCharsets.UTF_8), new byte[]{0x0d, 0x0a});
    }

    //$CCTCQ,1234567,2,1,1,测试十个字测试十个字,0*74\r\n
    public static byte[] encodeBd3SendMsg(byte[] cmd, String remoteBdNo) throws UnsupportedEncodingException {
        String beCheck = "CCTCQ," + StringUtils.leftPad(remoteBdNo, 7, '0') + ",2,1,2,"
                + ByteUtil.bytesToHex(cmd) + ",0";
        String checkResult = ByteUtil.byteToHex(ByteUtil.xorCheck(beCheck.getBytes("GBK")));
        return ("$" + beCheck + "*" + checkResult + "\r\n").getBytes(StandardCharsets.UTF_8);
    }

    public static BdRes getResFromTXSQ(byte[] bdBytes) {
        BdRes res = new BdRes();
        res.setContent(Arrays.copyOfRange(bdBytes, 17, bdBytes.length - 1));
        return res;
    }

    public static byte[] genTXXX(byte[] cmd, String localBdNo, String remoteBdNo, LocalDateTime dateTime) {
        String header = "$TXXX";
        byte[] length = ByteUtil.intToBytes(20 + cmd.length, 2);
        byte[] localAddress = ByteUtil.intToBytes(Integer.parseInt(localBdNo), 3);
        byte[] messageType = new byte[]{0x40};
        byte[] remoteAddress = ByteUtil.intToBytes(Integer.parseInt(remoteBdNo), 3);
        byte[] hour = ByteUtil.intToBytes(dateTime.getHour(), 1);
        byte[] minute = ByteUtil.intToBytes(dateTime.getMinute(), 1);
        byte[] contentLength = ByteUtil.intToBytes(cmd.length, 2);
        byte[] CRC = new byte[]{0x00};
        byte[] beCheck = ByteUtil.combineBytes(header.getBytes(StandardCharsets.UTF_8), length, localAddress, messageType
                , remoteAddress, hour, minute, contentLength, cmd, CRC);
        byte[] checkResult = new byte[]{ByteUtil.xorCheck(beCheck)};
        return ByteUtil.combineBytes(beCheck, checkResult, "\r\n".getBytes(StandardCharsets.UTF_8));
    }
}
